package com.mamingchao.issue.three;

import java.util.ArrayList;
import java.util.List;

/**
 * 解决问题思路：
 * 看过数学之美里面，关于搜索引擎 地图上搜索最优路线的算法
 * 使用图 + 迭代的方法，想到此问题也同理
 * 地图导航搜索最优路径，从起点a到t，中间可以切割a到b最优计算，b到c最优路径计算，..... 最终是s到t的最优路径计算
 * 其中切割分离出来的每个局部，都应该是最优的。比如 b到c如果有更优路线，那b到c应该换成 更优路线，a到t才能最优
 *
 * 所以，上面的理论，复用到小红杀怪这个上面，也不合适；因为上面的例子里，b c d等中间节点都是固定的，而此题不固定，a b x y的值不一样，节点就不一样
 *
 * 上网查里 有权图的最短路径算法；固定起点的 有Dijkstra（迪科斯彻）最短路算法；算所有节点之间的最短路径，用FLoyd（佛洛依德）算法
 * 但是这两种算法都是先用二维数据表示出图（邻接矩阵）来；当为稀疏表（边n的数量远小于节点m 的平方），用邻接表替代邻接矩阵，节省空间
 *
 * 如果想用图来实现，必须先把图算出来（画出来），然后再用二维数组表达，再套用上面的两个算法。这样做有点过于繁琐
 *
 *
 * 简单实现；用迭代，迭代里面的逻辑 有简单的判断；把a 和b 的血量加在一起当血量池
 *
 * 起点：满血的怪物a和b； 终点，怪物a和b 的血量都<=0
 *
 */
public class XiaoHongKillMonster {

    public static void main(String[] args) {
        int blood_a = 32;
        int blood_b = 51;
        int wizard_x = 10;
        int wizard_y = 5;
        int result = getUsedWizardTimes(blood_a, blood_b, wizard_x, wizard_y);

        System.out.println("小红击杀怪物，一共用了 " + result + " 次！");
    }

    /**
     *
     * @param blood_a 怪物A的血量
     * @param blood_b 怪物B的血量
     * @param wizard_x 小红单体技能x的血量伤害
     * @param wizard_y 小红群体技能y的血量伤害
     * @return
     */
    private static int getUsedWizardTimes(int blood_a, int blood_b, int wizard_x, int wizard_y) {

        MonsterStatus monsterStatus = new MonsterStatus(blood_a,blood_b);

        while (!monsterStatus.isKilled) {
            useWizard(monsterStatus, wizard_x , wizard_y);
        }

        monsterStatus.wizard_name.forEach(e -> {
            System.out.println(e);
        });

        return monsterStatus.wizard_num;
    }

    /**
     * 迭代的具体算法
     * @return 本次使用招数的结果
     */
    private static MonsterStatus useWizard(MonsterStatus monsterStatus, int x_harm_value, int y_harm_value ) {

        // 如果a 和 b 血量都小于等于0，怪物就完成击杀
        if (monsterStatus.blood_a_ <= 0 && monsterStatus.blood_b_ <= 0) {
            monsterStatus.wizard_name.add("怪物已经被击杀");
            monsterStatus.isKilled = true;
            return monsterStatus;
        }

        // 下面的逻辑，一定会触发 释放技能

        // 使用招数次数 + 1
        monsterStatus.wizard_num ++;


        //如果y技能对单个怪物的 血量伤害 大于等于x技能
        if (x_harm_value <= y_harm_value ) {
            monsterStatus.blood_a_ -= y_harm_value;
            monsterStatus.blood_b_ -= y_harm_value;
            monsterStatus.wizard_name.add("小红使用一次Y技能");
            return monsterStatus;
        }


        // 下面的是 y技能对单个怪物的 血量伤害 小于 x技能, 单总伤害量大于 x
        if (y_harm_value * 2 >= x_harm_value &&  x_harm_value > y_harm_value ) {

            if (monsterStatus.blood_a_ <= 0) {
                monsterStatus.blood_b_ -= x_harm_value;
                monsterStatus.wizard_name.add("小红对怪物b使用一次x技能");
                return monsterStatus;
            }else if (monsterStatus.blood_b_ <= 0) {
                monsterStatus.blood_a_ -= x_harm_value;
                monsterStatus.wizard_name.add("小红对怪物a使用一次x技能");
                return monsterStatus;
            } else {
                monsterStatus.blood_a_ -= y_harm_value;
                monsterStatus.blood_b_ -= y_harm_value;
                monsterStatus.wizard_name.add("小红使用一次Y技能");
                return monsterStatus;
            }
        }


        // x技能的伤害 比 y技能的伤害总量大
        if (x_harm_value > y_harm_value * 2 ) {

            if (monsterStatus.blood_a_ <= 0 ) {
                monsterStatus.blood_b_ -= x_harm_value;
                monsterStatus.wizard_name.add("小红对怪物b使用一次x技能");
                return monsterStatus;
            }

            if (monsterStatus.blood_b_ <= 0) {
                monsterStatus.blood_a_ -= x_harm_value;
                monsterStatus.wizard_name.add("小红对怪物a使用一次x技能");
                return monsterStatus;
            }

            if ( monsterStatus.blood_a_ <= y_harm_value ) {
                monsterStatus.blood_a_ -= y_harm_value;
                monsterStatus.blood_b_ -= y_harm_value;
                monsterStatus.wizard_name.add("小红使用一次Y技能");
                return monsterStatus;
            }

            if (monsterStatus.blood_b_ <= y_harm_value ) {
                monsterStatus.blood_a_ -= y_harm_value;
                monsterStatus.blood_b_ -= y_harm_value;
                monsterStatus.wizard_name.add("小红使用一次Y技能");
                return monsterStatus;
            }

            if ( monsterStatus.blood_a_ > y_harm_value ) {
                monsterStatus.blood_a_ -= x_harm_value;
                monsterStatus.wizard_name.add("小红对怪物a使用一次x技能");
                return monsterStatus;
            }

            if (monsterStatus.blood_b_ > y_harm_value ) {
                monsterStatus.blood_b_ -= x_harm_value;
                monsterStatus.wizard_name.add("小红对怪物b使用一次x技能");
                return monsterStatus;
            }
        }

        return monsterStatus;
    }



    private int getMinimunNum(int num_a, int num_b){
        return Math.min(num_a, num_b);
    }

    /**
     * 每次使用招数后，怪物剩余的血量
     * 本次招数使用的是哪一找
     */
    static class MonsterStatus {
        // 怪物a在一次招数后 剩余的血量
        int blood_a_;

        // 怪物b在一次招数后 剩余的血量
        int blood_b_;

        // 本次出招使用的招数名称
        List<String> wizard_name = new ArrayList<>();

        // 使用招数次数
        int wizard_num;

        // 是否被击杀来
        boolean isKilled;

        public MonsterStatus(int blood_a_, int blood_b_) {
            this.blood_a_ = blood_a_;
            this.blood_b_ = blood_b_;
        }
    }
}
